package foo;

import java.util.Arrays;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.commons.cli.BasicParser;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.lang.StringUtils;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Hello world!
 * 
 */
public class App {
	private final Object monitorObject = new Object();

	static {
		System.out.println("this is a static method");
	}

	public static void main(final String[] args) throws Exception {
		System.out.println("This is the main method");
		final Object a = new Object();
		System.err.println(a.hashCode());
		System.err.println(a.equals(a));

	}

	private static void parseCommandLineArguments(final String[] args) throws ParseException {
		final CommandLineParser parser = new BasicParser();
		final Options options = new Options();
		options.addOption("a", "opta", true, "Option A");
		options.addOption("b", "optb", true, "Option B");

		final CommandLine commandLine = parser.parse(options, args);

		final String optionA = getOption('a', commandLine);
		final String optionB = getOption('b', commandLine);

		final String[] remainingArguments = commandLine.getArgs();

		System.out.println(String.format("OptionA: %s, OptionB: %s", optionA, optionB));
		System.out.println("Remaining arguments: " + Arrays.toString(remainingArguments));
	}

	public static String getOption(final char option, final CommandLine commandLine) {

		if (commandLine.hasOption(option)) {
			return commandLine.getOptionValue(option);
		}

		return StringUtils.EMPTY;
	}

	public void run() throws Exception {
		// builderPattern();
		// runMultiThreadedServer();
		final ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(
				"applicationContext.xml");

		final ArithmeticCalculator calculator = applicationContext.getBean(ArithmeticCalculator.class);
		System.out.println(calculator.add(10, 20));
		Thread.sleep(5000);
		applicationContext.destroy();
	}

	private void runMultiThreadedServer() {
		final MultiThreadedServer server = new MultiThreadedServer(9000);
		new Thread(server).start();

		synchronized (monitorObject) {
			try {
				monitorObject.wait();
			} catch (final InterruptedException e) {
				throw new RuntimeException(e);
			}
		}

		System.err.println("Stopping Server");
		server.stop();

	}

	public void builderPattern() {
		final Lock lock = new ReentrantLock();
		lock.lock();

		try {
			System.out.println("Hello world. I have the lock now");
			System.out.println(new Pid().withRegion("UK").withAvailabilityZone("London").build());

		} finally {
			lock.unlock();
		}
	}
}